//+------------------------------------------------------------------+
//|              ChartObjectsBmpControls.mqh MQL5 图表位图控件头文件  |
//|                版权所有 2000-2025, MetaQuotes Ltd.              |
//|                        官方网址: https://www.mql5.com            |
//+------------------------------------------------------------------+
//| 包含所有基于位图（BMP）的图表控件类（位图对象、位图标签）           |
//+------------------------------------------------------------------+
#include "ChartObject.h"  // 引入图表对象基类 CChartObject（提供通用属性与生命周期管理）

//+------------------------------------------------------------------+
//| CChartObjectBitmap 类（图表位图对象）                             |
//| 功能：MQL5 图表位图对象，在指定 K 线时间与价格位置显示 BMP 图片    |
//| 继承关系：public CChartObject（基于图表对象基类，扩展位图特有属性）|
//| 核心特性：                                                      |
//|  1. 绑定 K 线坐标：图片位置由时间（Time）和价格（Price）确定，随图表缩放移动 |
//|  2. 偏移微调：支持 X/Y 方向像素偏移，微调图片相对于坐标点的位置      |
//|  3. 图片配置：可设置 BMP 图片文件路径（本地文件或 MT5 资源文件）     |
//|  4. 继承通用属性：颜色（透明色控制）、可见周期、Z-Order 等          |
//+------------------------------------------------------------------+
class CChartObjectBitmap : public CChartObject
  {
public:
   /**
    * @brief 构造函数：初始化图表位图对象
    * @details 调用父类 CChartObject 构造函数，初始化位图对象的基础属性（未绑定图表）
    */
                     CChartObjectBitmap(void);

   /**
    * @brief 析构函数：销毁图表位图对象
    * @details 依赖父类析构逻辑，自动删除图表上的位图对象，释放资源
    */
                    ~CChartObjectBitmap(void);

   //--- 位图对象特有属性接口
   /**
    * @brief 获取当前显示的 BMP 图片文件路径
    * @return string - 图片文件路径（本地绝对路径或 MT5 资源路径，如 "::Images/icon.bmp"，空字符串表示未设置）
    */
   string            BmpFile(void) const;

   /**
    * @brief 设置要显示的 BMP 图片文件
    * @param name [in] 图片文件路径（支持本地文件或 MT5 资源文件，需为 BMP 格式）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表/文件不存在）
    */
   bool              BmpFile(const string name) const;

   /**
    * @brief 获取图片在 X 方向的像素偏移量（相对于坐标点的微调）
    * @return int - X 偏移量（像素，正数向右偏移，负数向左偏移，0 表示无偏移）
    */
   int               X_Offset(void) const;

   /**
    * @brief 设置图片在 X 方向的像素偏移量
    * @param X [in] 新 X 偏移量（像素，建议范围 -50~50，避免偏移过大导致图片脱离坐标点）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              X_Offset(const int X) const;

   /**
    * @brief 获取图片在 Y 方向的像素偏移量（相对于坐标点的微调）
    * @return int - Y 偏移量（像素，正数向上偏移，负数向下偏移，0 表示无偏移）
    */
   int               Y_Offset(void) const;

   /**
    * @brief 设置图片在 Y 方向的像素偏移量
    * @param Y [in] 新 Y 偏移量（像素，建议范围 -50~50）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              Y_Offset(const int Y) const;

   //--- 位图对象创建接口
   /**
    * @brief 在指定图表创建位图对象（绑定到 K 线时间与价格坐标）
    * @param chart_id [in] 目标图表 ID（0 表示当前图表，可通过 ChartID() 获取）
    * @param name [in] 位图对象唯一名称（图表内不可重复）
    * @param window [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @param time [in] 绑定的 K 线时间（如 D'2024.01.01'，图片随该 K 线移动）
    * @param price [in] 绑定的价格坐标（如 1.20000，图片垂直位置对应此价格）
    * @return bool - 操作结果：true 表示创建成功（对象创建+绑定完成），false 表示失败
    * @note 创建后需通过 BmpFile 方法设置图片，否则仅显示空白；偏移量默认为 0
    */
   bool              Create(long chart_id,const string name,const int window,const datetime time,const double price);

   //--- 对象类型标识（重写基类方法）
   /**
    * @brief 获取位图对象类型（MQL5 预定义类型）
    * @return int - 对象类型标识（返回 OBJ_BITMAP，代表图表位图对象）
    */
   virtual int       Type(void) const { return(OBJ_BITMAP); }

   //--- 序列化接口（重写基类方法，扩展位图特有属性的读写）
   /**
    * @brief 将位图对象参数（含特有属性）保存到文件
    * @param file_handle [in] 文件句柄（需提前以 FILE_WRITE 模式打开）
    * @return bool - 操作结果：true 表示保存成功，false 表示失败（文件无效/未绑定图表）
    * @note 保存内容：基类通用属性 + BMP 图片路径 + X/Y 偏移量
    */
   virtual bool      Save(const int file_handle);

   /**
    * @brief 从文件加载位图对象参数（含特有属性）
    * @param file_handle [in] 文件句柄（需提前以 FILE_READ 模式打开）
    * @return bool - 操作结果：true 表示加载成功，false 表示失败（文件无效/未绑定图表）
    * @note 加载后覆盖图片路径与偏移量，需确保文件为 Save 方法生成的格式
    */
   virtual bool      Load(const int file_handle);
  };

//+------------------------------------------------------------------+
//| CChartObjectBmpLabel 类（图表位图标签控件）                       |
//| 功能：MQL5 图表位图标签，在固定屏幕位置显示 BMP 图片，支持状态切换  |
//| 继承关系：public CChartObject（基于图表对象基类，扩展标签特有属性）|
//| 核心特性：                                                      |
//|  1. 固定屏幕位置：由基准角（Corner）和 X/Y 距离（Distance）确定，不随图表缩放移动 |
//|  2. 双状态切换：支持 ON/OFF 两种状态，分别显示不同 BMP 图片（如按钮按下/弹起） |
//|  3. 尺寸自适应：图片尺寸由 BMP 文件实际尺寸决定，不可手动修改        |
//|  4. 禁止坐标修改：屏蔽基类的 Time/Price 方法，仅支持屏幕位置控制     |
//+------------------------------------------------------------------+
class CChartObjectBmpLabel : public CChartObject
  {
public:
   /**
    * @brief 构造函数：初始化图表位图标签
    * @details 调用父类 CChartObject 构造函数，初始化标签的基础属性（未绑定图表）
    */
                     CChartObjectBmpLabel(void);

   /**
    * @brief 析构函数：销毁图表位图标签
    * @details 依赖父类析构逻辑，自动删除图表上的标签对象，释放资源
    */
                    ~CChartObjectBmpLabel(void);

   //--- 位置与基准角属性接口
   /**
    * @brief 获取标签相对于基准角的 X 方向距离（屏幕像素）
    * @return int - X 距离（像素，从基准角向右的距离）
    */
   int               X_Distance(void) const;

   /**
    * @brief 设置标签相对于基准角的 X 方向距离
    * @param X [in] 新 X 距离（像素，建议根据图表尺寸设置，如 10 表示距离基准角右侧 10 像素）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              X_Distance(const int X) const;

   /**
    * @brief 获取标签相对于基准角的 Y 方向距离（屏幕像素）
    * @return int - Y 距离（像素，从基准角向下的距离）
    */
   int               Y_Distance(void) const;

   /**
    * @brief 设置标签相对于基准角的 Y 方向距离
    * @param Y [in] 新 Y 距离（像素，如 10 表示距离基准角下方 10 像素）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              Y_Distance(const int Y) const;

   //--- 尺寸属性接口（只读，由图片尺寸决定）
   /**
    * @brief 获取标签的实际宽度（等于 BMP 图片的宽度）
    * @return int - 宽度（像素，0 表示未设置图片或获取失败）
    */
   int               X_Size(void) const;

   /**
    * @brief 获取标签的实际高度（等于 BMP 图片的高度）
    * @return int - 高度（像素，0 表示未设置图片或获取失败）
    */
   int               Y_Size(void) const;

   /**
    * @brief 获取标签的基准角（屏幕参考角）
    * @return ENUM_BASE_CORNER - 基准角（如 CORNER_LEFT_UPPER 表示左上角，CORNER_RIGHT_LOWER 表示右下角）
    */
   ENUM_BASE_CORNER  Corner(void) const;

   /**
    * @brief 设置标签的基准角（改变参考坐标系）
    * @param corner [in] 新基准角（需为 ENUM_BASE_CORNER 枚举值）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    * @note 基准角改变后，X/Y 距离的参考原点也会变化（如左上角→右上角）
    */
   bool              Corner(const ENUM_BASE_CORNER corner) const;

   //--- 双状态图片属性接口
   /**
    * @brief 获取 ON 状态下显示的 BMP 图片路径
    * @return string - ON 状态图片路径（空字符串表示未设置）
    */
   string            BmpFileOn(void) const;

   /**
    * @brief 设置 ON 状态下显示的 BMP 图片
    * @param name [in] 图片路径（支持本地文件或 MT5 资源文件，需为 BMP 格式）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表/文件不存在）
    */
   bool              BmpFileOn(const string name) const;

   /**
    * @brief 获取 OFF 状态下显示的 BMP 图片路径
    * @return string - OFF 状态图片路径（空字符串表示未设置）
    */
   string            BmpFileOff(void) const;

   /**
    * @brief 设置 OFF 状态下显示的 BMP 图片
    * @param name [in] 图片路径（支持本地文件或 MT5 资源文件，需为 BMP 格式）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表/文件不存在）
    * @note ON/OFF 状态图片建议尺寸一致，避免切换时标签大小跳动
    */
   bool              BmpFileOff(const string name) const;

   //--- 状态切换接口
   /**
    * @brief 获取标签当前状态（ON/OFF）
    * @return bool - 状态值（true=ON 状态，显示 BmpFileOn 图片；false=OFF 状态，显示 BmpFileOff 图片）
    */
   bool              State(void) const;

   /**
    * @brief 设置标签状态（切换显示的图片）
    * @param state [in] 新状态（true=ON，false=OFF）
    * @return bool - 操作结果：true 表示状态切换成功，false 表示失败（未绑定图表）
    */
   bool              State(const bool state) const;

   //--- 偏移微调接口（类似位图对象，微调图片位置）
   /**
    * @brief 获取标签在 X 方向的像素偏移量
    * @return int - X 偏移量（像素，正数向右偏移，负数向左偏移）
    */
   int               X_Offset(void) const;

   /**
    * @brief 设置标签在 X 方向的像素偏移量
    * @param X [in] 新 X 偏移量（像素，建议范围 -20~20）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              X_Offset(const int X) const;

   /**
    * @brief 获取标签在 Y 方向的像素偏移量
    * @return int - Y 偏移量（像素，正数向上偏移，负数向下偏移）
    */
   int               Y_Offset(void) const;

   /**
    * @brief 设置标签在 Y 方向的像素偏移量
    * @param Y [in] 新 Y 偏移量（像素，建议范围 -20~20）
    * @return bool - 操作结果：true 表示设置成功，false 表示失败（未绑定图表）
    */
   bool              Y_Offset(const int Y) const;

   //--- 禁止时间/价格坐标修改（重写基类方法，返回 false 屏蔽功能）
   /**
    * @brief 禁止修改时间坐标（位图标签不绑定 K 线时间，此方法始终返回 false）
    * @param time [in] 无效参数（无论传入何值均不生效）
    * @return bool - 操作结果：始终返回 false
    */
   bool              Time(const datetime time) const { return(false); }

   /**
    * @brief 禁止修改价格坐标（位图标签不绑定价格，此方法始终返回 false）
    * @param price [in] 无效参数（无论传入何值均不生效）
    * @return bool - 操作结果：始终返回 false
    */
   bool              Price(const double price) const { return(false); }

   //--- 位图标签创建接口
   /**
    * @brief 在指定图表创建位图标签（绑定到屏幕固定位置）
    * @param chart_id [in] 目标图表 ID（0 表示当前图表）
    * @param name [in] 标签唯一名称（图表内不可重复）
    * @param window [in] 子窗口编号（0=主窗口，≥1=指标子窗口）
    * @param X [in] 相对于基准角的 X 距离（像素，基准角默认左上角）
    * @param Y [in] 相对于基准角的 Y 距离（像素）
    * @return bool - 操作结果：true 表示创建成功（对象创建+绑定+位置设置完成），false 表示失败
    * @note 创建后需通过 BmpFileOn/BmpFileOff 设置双状态图片，默认状态为 OFF
    */
   bool              Create(long chart_id,const string name,const int window,const int X,const int Y);

   //--- 对象类型标识（重写基类方法）
   /**
    * @brief 获取位图标签类型（MQL5 预定义类型）
    * @return int - 对象类型标识（返回 OBJ_BITMAP_LABEL，代表图表位图标签）
    */
   virtual int       Type(void) const { return(OBJ_BITMAP_LABEL); }

   //--- 序列化接口（重写基类方法，扩展标签特有属性的读写）
   /**
    * @brief 将位图标签参数（含特有属性）保存到文件
    * @param file_handle [in] 文件句柄（需提前以 FILE_WRITE 模式打开）
    * @return bool - 操作结果：true 表示保存成功，false 表示失败（文件无效/未绑定图表）
    * @note 保存内容：基类通用属性 + 基准角 + X/Y 距离 + ON/OFF 图片路径 + 当前状态 + 偏移量
    */
   virtual bool      Save(const int file_handle);

   /**
    * @brief 从文件加载位图标签参数（含特有属性）
    * @param file_handle [in] 文件句柄（需提前以 FILE_READ 模式打开）
    * @return bool - 操作结果：true 表示加载成功，false 表示失败（文件无效/未绑定图表）
    */
   virtual bool      Load(const int file_handle);
  };
//+------------------------------------------------------------------+